package com.tc.data.test.strategy.table;


import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author tim01.wei
 */
public class BaseTableShardingStrategy {
    public String getTargetSql(String sql, Object object) {
        String targetSql = "";
        if (object instanceof Date) {
            targetSql = getDateStrategy(sql, (Date) object);
        } else if (object instanceof Long) {
            targetSql = getOrderIdStrategy(sql, (Long) object);
        }else if (object instanceof String) {
            targetSql = getStringStrategy(sql, (String) object);
        }
        return targetSql;
    }

    private String getStringStrategy(String sql, String date) {
        // yyyyMM
        String name = getMatchTableName(sql);
        String realTableName = String.format("%s%s", name, date);
        return getShardingTableName(name, realTableName, sql);
    }

    private String getDateStrategy(String sql, Date date) {
        // yyyyMM
        String tablePostfix = new SimpleDateFormat(" yyyyMM").format(date);
        String name = getMatchTableName(sql);
        String realTableName = String.format("%s%s", name, tablePostfix);
        return getShardingTableName(name, realTableName, sql);
    }

    private String getOrderIdStrategy(String sql, Long orderId) {
        // orderId的生成规则是yyMMdd+8位seq+4位，该处取开始的yyMM
        String tablePostfix = orderId.toString().substring(0, 4);
        String name = getMatchTableName(sql);
        // 要求mybatis的映射文件中 的表名标识${table_name}中的table_name为拿掉日期后的表名
        String realTableName = String.format("%s20%s", name, tablePostfix);
        return getShardingTableName(name, realTableName, sql);
    }


    public static String getMatchTableName(String sql) {
        Assert.hasText(sql);
        Pattern pattern = Pattern.compile("\\$\\[.*?\\]\\$");
        Matcher matcher = pattern.matcher(sql);
        while (matcher.find()) {
            String name = matcher.group();
            return name.substring(2, name.length() - 2);
        }
        return null;
    }

    public static String getShardingTableName(String tableName, String realTableName, String sql) {
        Assert.hasText(tableName);
        Assert.hasText(realTableName);
        Assert.hasText(sql);
        return sql.replaceAll(getRegexTableName(tableName), realTableName);
    }

    public static String getRegexTableName(String tableName) {
        Assert.hasText(tableName);
        return "\\$\\[" + tableName + "\\]\\$";
    }

}
